/**
说明:
1.STR_NUM宏为需要发送的字符串的个数+1，这些字符串被存储在指针数组pstr中。
2.如果只是需要发送数据而不读取数据，则取消DEGUB宏的定义。
3.默认的串口设备是"/dev/ttyUSB0"，可以修改宏DEFAULT_DEV的定义来设定需要的串口设备。
4.如果需要发送main函数接受的参数而不是pstr指针数据中静态初始化的字符串，则需要定义FROM_ARGV宏（默认情况下该宏未被定义）。
5.如果需要发送不可打印字符，可以参照程序中pstr数组的最后一个元素的形式（(char *)26）。
6.超时等待时间由DEFAULT_INTERVAL宏决定，可以修改它以适应具体需要。
7.默认串口参数： 波特率：9600 数据位:8 停止位:1 校验: 无 串口设备: /dev/ttyUSB0（该设备为USB转串口设备）。如果需要修改这些参数，只需要修改对应的宏定义即可。
*/
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>

#include "pic.h"
#include "hello.h"

#define TRUE 0
#define FALSE -1
#define DEFAULT_DEV "/dev/ttyGS0"
#define DEFAULT_BAUND B9600
#define DEFAULT_DATABIT CS8
#define DEFAULT_PAR ~PARENB
#define DEFAULT_INP ~INPCK
#define DEFAULT_STOPBIT ~CSTOPB
#define DEFAULT_INTERVAL 11
#define STR_NUM 9

#define MAX 10

char * FILE_NAME = "1.txt";     
//#define FROM_ARGV
//测试模式下读取程序读取串口内容
#ifdef DEBUG 
#define READ_BUFFER_SIZE 32
#endif
//如果没有定义宏FROM_ARGV则定义pstr为指针数组，其各个元素所指向的内容为需要发送的数据
#ifndef FROM_ARGV
static const char *pstr[] = {0, "AT", "AT", "AT+CMGF=1", "AT+CMGS=", "\"", "13474669578", "\"", ";\r", (char *)26};
#else  //否则pstr被重新重命名为argv，程序将发送main函数接受的字符串参数
#define pstr argv
#endif

int open_dev(const char *dev_name);
int set_port(const int fd);
int open_port(const char *dev_name);
int send_data(const int fd, const char *buffer, const int buffer_len);
#ifdef DEBUG
int read_data(const int fd, char *read_buffer);
#endif

int send_data_usb(char *data, int len,char channel,int frame_numb,int fid);



char *dev_name = DEFAULT_DEV;
int fd;

//打开串口
int uart_init(const char *dev_name )
{
    int fd=0;    
    fd = open(dev_name, O_RDWR|O_NOCTTY|O_NDELAY, 0);    
    if (fd < 0) 
    {        
        printf("open error!\n");        
        return -1;
    }    
    //set_port(fd);    
    return  fd;
}
int open_dev(const char *dev_name)
{
    return open(dev_name, O_RDWR);
}
int set_port(const int fd)
{
    //设置速率
    struct termios opt;
    if(tcgetattr(fd, &opt) != 0){
    return FALSE;
    }
    cfsetispeed(&opt, DEFAULT_BAUND);
    cfsetospeed(&opt,DEFAULT_BAUND);
    tcsetattr(fd,TCSANOW,&opt);
    opt.c_cflag &= ~CSIZE;
    //设置数据位
    opt.c_cflag |= DEFAULT_DATABIT;
    //设置校验位
    opt.c_cflag &= DEFAULT_PAR;
    opt.c_iflag &= DEFAULT_INP;
    //设置停止位
    opt.c_cflag &= DEFAULT_STOPBIT;
    tcflush(fd, TCIFLUSH);
    opt.c_cc[VTIME] = DEFAULT_INTERVAL;
    opt.c_cc[VMIN] = 0;
    if(tcsetattr(fd, TCSANOW, &opt) != 0){
    return FALSE;
    }
    return TRUE;
}
//发送数据    
int send_data(const int fd, const char *buffer, const int buffer_len)
{
    return write(fd, buffer, buffer_len);
}
#ifdef DEBUG
//读取数据
int read_data(const int fd, char *read_buffer)
{
    return read(fd, read_buffer, READ_BUFFER_SIZE);
}
#endif





int send_data_usb(char *data, int len,char channel,int frame_numb,int fid){

    char pack_channel=channel;
    int pack_fid=fid;
    int frame_number=frame_numb;
   // int value_len=256;
    int data_len=len+5;
    if(data_len>600)
    {
        return 1;
    }
    char send_buf[600]={0};
    send_buf[0]=0x55;
    send_buf[1]=0xAA;
    send_buf[2]=(char)(data_len>>8);
    send_buf[3]=(char)data_len;
    send_buf[4]=pack_channel;
    send_buf[5]=(char)(frame_number>>8);
    send_buf[6]=(char)frame_number;
    send_buf[7]=(char)(pack_fid>>8);
    send_buf[8]=(char)pack_fid;
    memcpy(&send_buf[9],data,len);
    int checksum=cal_crc16((char *)&send_buf[2],data_len+2);
    send_buf[len+9]=(char)(checksum>>8);
    send_buf[len+10]=(char)checksum;

    send_data(fd,send_buf,data_len+6);
    return 0;
}
void test_tool(void){






}

int main(int argc, char *argv[])
{

    #ifdef DEBUG
        char read_buffer[READ_BUFFER_SIZE];
        int read_buffer_size;
    #endif
    build_crc16_table();
    FILE * pfile;  
    int read_len, i, c;  
    //打开串口
    if((fd = uart_init(dev_name)) == FALSE){
        perror("open error!");
        return -1;
    }
    //设置串口
    if(set_port(fd) == FALSE){
        perror("set error!");
        return -1;
    }
    printf("serial Open successed!\n");  
   char filename[80];

   long length;
 
    printf("输入文件名:");
    gets(filename);

    printf("文件名:%s",filename);
    pfile = fopen(filename,"rb");  
   
    size_t result;
    if(pfile == NULL)  
    {  
       perror("errno");  
    }
    else   
    {
       printf("File Open successed!\n");  
       if (1)
       {
        char *spread;
        
       fseek(pfile,0,SEEK_END);//将文件内部的指针指向文件末尾
       long lsize=ftell(pfile);//获取文件长度，（得到文件位置指针当前位置相对于文件首的偏移字节数）
       printf("get filesize 0x%x!\n",lsize);  
       rewind(pfile);//将文件内部的指针重新指向一个流的开头
       //fseek(pfile, 0, SEEK_SET);
       spread=(char *) malloc(lsize*sizeof(char)+1);//申请内存空间，lsize*sizeof(char)是为了更严谨，16位上char占一个字符，其他机器上可能变化
       //用malloc申请的内存是没有初始值的，如果不赋值会导致写入的时候找不到结束标志符而出现内存比实际申请值大，写入数据后面跟随乱码的情况
       memset(spread,0,lsize*sizeof(char)+1);//将内存空间都赋值为‘\0’
       
       result=fread(spread,1,lsize+1,pfile);//将pfile中内容读入pread指向内存中
       fclose(pfile);//关掉文件操作符，和句柄一样，有open就一定有close
       
        char *tpread;
        char tsize=4;
        tpread=(char *) malloc(tsize*sizeof(char)+1);//申请内存空间，lsize*sizeof(char)是为了更严谨，16位上char占一个字符，其他机器上可能变化
       //用malloc申请的内存是没有初始值的，如果不赋值会导致写入的时候找不到结束标志符而出现内存比实际申请值大，写入数据后面跟随乱码的情况
        memset(tpread,0,tsize*sizeof(char)+1);//将内存空间都赋值为‘\0’
       
        //result=fread(pread,1,lsize+1,pfile);//将pfile中内容读入pread指向内存中
        //00010118
        thread_create();
        tpread[0]=0;
        tpread[1]=1;
        tpread[2]=1;
        tpread[3]=18;
        while (1)
        {
            send_pack_data(spread,lsize,PICTSTREAM);

           
            if (tpread[3]>0)
            {
                tpread[3]--;
                /* code */
            }else
            {
                tpread[3]=255;
            }
            
            printf("send finish\r\n");
            //sleep(1);
        // usleep(100000);
        }
    
       


       close(fd);
       free(spread);//释放内存
       free(tpread);//释放内存
       spread=NULL;//指针不再使用，一定要“删除”，防止产生野指针
       tpread=NULL;
           /* code */
       }
       
       
    }  
    printf("File Open successed!\n");  
    return 0;
}